<template>
  <div>
    <CategorySelector :disabled="isListView === false"></CategorySelector>
    <el-card v-if="isListView" style="margin-top: 20px">
      <template #header>
        <el-button
          type="primary"
          :disabled="category3Id === ''"
          @click="toggleToAddOrEditViewHandler()"
          icon="ele-Plus"
          >添加属性</el-button
        >
      </template>
      <el-table :data="attrs">
        <el-table-column
          width="100px"
          label="序号"
          type="index"
        ></el-table-column>
        <el-table-column label="属性名称" prop="attrName"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template #="{ row }">
            <el-tag
              type="success"
              v-for="attrValue in row.attrValueList"
              :key="attrValue.id"
              style="margin-right: 10px"
              >{{ attrValue.valueName }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column width="200px" label="操作">
          <template #="{ row }">
            <el-button
              type="warning"
              icon="ele-Edit"
              @click="toggleToAddOrEditViewHandler(row)"
            ></el-button>
            <el-popconfirm
              title="是否要删除该数据?"
              @confirm="attrDeleteConfirmHandler(row.id)"
            >
              <template #reference>
                <el-button type="danger" icon="ele-Delete"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <el-card v-else style="margin-top: 20px">
      <el-form inline @submit.prevent>
        <el-form-item label="属性名">
          <!--
          因为 ? ts用完以后还会保留，Vue 模板中不能使用 ?
          ! TS 中  的一符号，排除 undefined|null，它会在 ts 编译完成以后除去的，所以不影响代码执行
          -->
          <el-input
            v-model="formData!.attrName"
            clearable
            @blur="enterAttrNameHandler"
            @keydown.enter="enterAttrNameHandler"
            ref="attrNameInputRef"
          />
        </el-form-item>
      </el-form>
      <div>
        <el-button
          type="primary"
          @click="addAttrValueHandler"
          :disabled="formData!.attrName == ''"
          >添加属性值</el-button
        >
        <el-button @click="isListView = true">取消</el-button>
      </div>
      <el-table style="margin: 20px 0" :data="formData!.attrValueList">
        <el-table-column width="100" label="序号" type="index">
        </el-table-column>
        <el-table-column label="属性值名称">
          <template #="{ row }">
            <!-- 如果当前 row 和 currentEditAttrValue 这个值是一样的，那么就表示这条数据是编辑状态 -->
            <span
              v-if="row != currentEditAttrValue"
              @click="enterFocusStatusHandler(row)"
              >{{ row.valueName }}</span
            >
            <el-input
              v-else
              @blur="enterAttrValueHandler"
              @keydown.enter="enterAttrValueHandler"
              v-model="row.valueName"
              ref="attrValueInputRef"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #="{ row }">
            <el-button
              type="danger"
              icon="ele-Delete"
              @click="removeAttrValueHandler(row)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
      <div>
        <el-button
          type="primary"
          @click="saveHandler"
          :disabled="formData!.attrValueList?.length == 0 || formData!.attrName ==''"
          >保存</el-button
        >
        <el-button @click="isListView = true">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "ProductAttr",
});
</script>
<script lang="ts" setup>
import CategorySelector from "@/components/CategorySelector/index.vue";
import * as apis from "@/api/attr";
import { useCategorySelectorStore } from "@/stores/categorySelector";
import { storeToRefs } from "pinia";
import { watch, ref, nextTick } from "vue";
import { ElMessage } from "element-plus";
import type { IAddOrEditAttr, IAttr, IAttrValue } from "@/api/attr";
import { cloneDeep } from "lodash";

const categorySelectorStore = useCategorySelectorStore();

//是否为显示列表的状态
const isListView = ref(true);
//从仓库中解构需要用的数据
const { category1Id, category2Id, category3Id } = storeToRefs(
  categorySelectorStore
);
//存储获取到的平台属性数据
const attrs = ref<IAttr[]>([]);

//收集添加或编辑的数据
const formData = ref<IAddOrEditAttr>();

//获取属性值输入框的dom元素
const attrValueInputRef = ref<HTMLInputElement>();
//
//记录当前进入编辑状态的数据AttrValue
const currentEditAttrValue = ref<Partial<IAttrValue>>();
//
//获取属性名输入框的dom元素
const attrNameInputRef = ref<HTMLInputElement>();
async function getAttrList() {
  // console.log("发送请求", category3Id);
  //如果category3Id的值变成了空字符串 那么就不能发送请求,并且要把attrs的重置
  if (category3Id.value === "") {
    return (attrs.value = []);
  }

  try {
    attrs.value = await apis.requestAttrInfoList(
      category1Id.value as number,
      category2Id.value as number,
      category3Id.value as number
    );
  } catch (e) {
    ElMessage.error("请求平台属性失败");
  }
}

//当仓库中的category3Id有值的时候,或者值发生变化的时候,才发送请求
watch(category3Id, getAttrList, {
  immediate: true,
});

//点击添加按钮切换到添加或者编辑的视图
function toggleToAddOrEditViewHandler(data?: IAttr) {
  isListView.value = false;
  //对formData的数据初始化
  if (!data) {
    //添加的时候初始化formData
    formData.value = {
      attrName: "",
      attrValueList: [],
      categoryId: category3Id.value as number,
      categoryLevel: 3,
    };
  } else {
    //编辑的时候初始化formData
    //直接赋值 formData改了 对应attrs中的那条数据也会变化
    // formData.value = data;
    //不能直接赋值 如果存在子数据 那么子数据之间的引用关系还是没有切断
    // formData.value = {
    //   ...data,
    //   ...{
    //     attrValueList: [...data.attrValueList],
    //   },
    // };
    //我们可以使用深拷贝来实现赋值
    formData.value = cloneDeep(data);
  }
}

//提交保存(新增,编辑)
async function saveHandler() {
  // console.log(formData.value);
  try {
    if (formData.value) {
      await apis.requestSaveOrUpdateAttr(formData.value);
      ElMessage.success("保存成功");
      //切换视图页面
      isListView.value = true;
      //获取最新的属性列表
      getAttrList();
    }
  } catch (e) {
    ElMessage.error("保存失败");
  }
}

//添加属性值 fromData.attrValueList数组中
function addAttrValueHandler() {
  const data = {
    valueName: "",
  };
  // 把当前这条新增数据添加到 attrValueList 中
  formData.value?.attrValueList?.push(data);

  // 同时在把这条数据添加到 currentEditAttrValue 中
  currentEditAttrValue.value = data;

  //设置焦点(需要使用nextTick)
  nextTick(() => {
    attrValueInputRef.value?.focus();
  });
}

//当 attrValue 对应的 input 失去焦点 或 按下回车键的时候
function enterAttrValueHandler() {
  //当前输入的值是否为空
  if (currentEditAttrValue.value!.valueName == "") {
    //从formData.value?.attrValueList 删除这条数据
    formData.value!.attrValueList = formData.value?.attrValueList?.filter(
      (item) => item != currentEditAttrValue.value
    );
  }
  //查询当前输入的值是否重复,从formData.value?.attrValueList数组中进行查询
  //currentEditAttrValue的值一定在formData.value?.attrValueList这个数组中存在,所以在查重的时候一定要排除自身的比较
  const isExists = formData.value?.attrValueList?.find(
    (item) =>
      item != currentEditAttrValue.value &&
      item.valueName == currentEditAttrValue.value?.valueName
  );
  // console.log(isExists);
  if (isExists) {
    ElMessage.error("属性值不能重复");
    currentEditAttrValue.value!.valueName = "";
    nextTick(() => {
      attrValueInputRef.value!.focus();
    });
  } else {
    currentEditAttrValue.value = undefined;
  }
}

//点击表格中的 span ，使当前这条数据进入编辑状态
function enterFocusStatusHandler(val: IAttrValue) {
  currentEditAttrValue.value = val;
  nextTick(() => {
    attrValueInputRef.value?.focus();
  });
}

//属性名输入框失焦或者回车的时候
function enterAttrNameHandler() {
  //查询一下当前属性名是否已经存在了
  //查询当前formData.attrName的值 是否在attrs数组中已经存在了
  // 在编辑状态下，还应该排除自身，判断的时候，当前 formData 出了自身以外是否和其它的数据重名
  // 把自身这个数据排除掉
  // const noFormdataAttrs = attrs.value.filter(
  //   (item) => item.id != formData.value!.id
  // );
  // // console.log(noFormdataAttrs);
  // const isExists = noFormdataAttrs.find(
  //   (attr) => attr.attrName == formData.value!.attrName
  // );
  // 我们还可以简单一点
  const isExists = attrs.value.find(
    (attr) =>
      attr.id != formData.value!.id && attr.attrName == formData.value!.attrName
  );
  if (isExists) {
    ElMessage.error("不能添加已经存在属性名");
    formData.value!.attrName = "";
    nextTick(() => {
      attrNameInputRef.value?.focus();
    });
  }
}

//删除属性值
function removeAttrValueHandler(data: IAttrValue) {
  //从formData.value?.attrValueList 删除这条数据
  formData.value!.attrValueList = formData.value?.attrValueList?.filter(
    (item) => item != data
  );
}

//删除attr 确认提示

async function attrDeleteConfirmHandler(id: number) {
  //发送请求删除数据
  try {
    await apis.requestDeleteAttr(id);
    ElMessage.success("删除成功");
    //更新列表数据
    getAttrList();
  } catch (e) {
    ElMessage.error("删除失败");
  }
}
</script>
